package com.wzdigit.wms.wms.service.basic;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.wzdigit.framework.Shift;
import com.wzdigit.mes.basic.api.BasicDataItemDetailApi;
import com.wzdigit.mes.basic.dto.DataItemDetailDTO;
import com.wzdigit.wms.basic.client.PagerInfo;
import com.wzdigit.wms.basic.client.request.basic.*;
import com.wzdigit.wms.basic.client.response.Result;
import com.wzdigit.wms.basic.client.response.basic.ImportVehicleErrorResponse;
import com.wzdigit.wms.basic.client.response.basic.ImportVehicleResponse;
import com.wzdigit.wms.basic.client.response.basic.VehicleApiResponse;
import com.wzdigit.wms.basic.client.response.basic.VehicleResponse;
import com.wzdigit.wms.basic.domain.basic.Carrier;
import com.wzdigit.wms.basic.domain.basic.Vehicle;
import com.wzdigit.wms.basic.enums.BaseIsEnabledEnum;
import com.wzdigit.wms.basic.mapper.core.basic.CarrierMapper;
import com.wzdigit.wms.basic.mapper.core.basic.VehicleMapper;
import com.wzdigit.wms.basic.util.HttpSessionUtil;
import com.wzdigit.wms.basic.util.StringUtils;
import com.wzdigit.wms.common.utils.*;
import com.wzdigit.wms.common.entity.StatusCode;
import net.dreamlu.mica.core.utils.BeanUtil;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 车辆 服务类
 *
 * @author yangdongjie
 * @LocationAttrService.java
 * @2021年1月4日上午11:16:31
 */
@Service
public class VehicleService {

    @Autowired
    private VehicleMapper vehicleMapper;

    @Autowired
    private CarrierMapper carrierMapper;

    @Reference(version = "${dubbo.consumers.basic.data.item.detail.api:1.0.0}", check = false, timeout = 300000)
    private BasicDataItemDetailApi dataItemDetailApi;

    public List<VehicleApiResponse> list() {
        return vehicleMapper.selectAllByStatus(BaseIsEnabledEnum.USE.code);
    }

    public VehicleResponse getVehicle(Integer vehicleId) {
        return vehicleMapper.selectOneByVehicleId(vehicleId);
    }

    @SuppressWarnings("rawtypes")
    public <T> PagerInfo<List<VehicleResponse>> searchVehicle(SearchVehicleRequest dto) {
        Page<T> page = PageHelper.offsetPage(dto.getSkipCount(), dto.getMaxResultCount());
        PagerInfo<List<VehicleResponse>> pagerInfo = new PagerInfo<List<VehicleResponse>>();
        List<VehicleResponse> list = vehicleMapper.selectAll(dto);
        pagerInfo.setItems(list);
        pagerInfo.setTotalCount(page.getTotal());
        return pagerInfo;
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public VehicleResponse createVehicle(CreateVehicleRequest dto,
                                         HttpServletRequest servletRequest) {
        String loginName = HttpSessionUtil.getLoginName(servletRequest);
        Vehicle vehicle = vehicleMapper.selectOneByVehicleNoAndDriver(dto.getVehicleNo(), dto.getDriver());
        if (vehicle != null) {
            // 该车辆数据已存在
            Shift.fatal(StatusCode.VEHICLE_DATA_EXIST);
        }
        vehicle = new Vehicle();
        BeanUtil.copyNonNull(dto, vehicle);
        vehicle.setCreateUser(loginName);
        vehicle.setCreateTime(new Date());
        vehicleMapper.insert(vehicle);

        VehicleResponse response = new VehicleResponse();
        BeanUtil.copyNonNull(vehicle, response);
        return response;
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public VehicleResponse updateVehicle(UpdateVehicleRequest dto,
                                         HttpServletRequest servletRequest) {
        String loginName = HttpSessionUtil.getLoginName(servletRequest);
        Vehicle vehicle = vehicleMapper.selectOneByVehicleNoAndDriver(dto.getVehicleNo(), dto.getDriver());
        if (vehicle != null) {
            if (dto.getVehicleId().intValue() != vehicle.getVehicleId().intValue()) {
                // 该车辆数据已存在
                Shift.fatal(StatusCode.VEHICLE_DATA_EXIST);
            }
        }
        vehicle = vehicleMapper.selectByPrimaryKey(dto.getVehicleId());
        BeanUtil.copy(dto, vehicle);
        vehicle.setModifyUser(loginName);
        vehicle.setModifyTime(new Date());
        vehicleMapper.updateById(vehicle);

        VehicleResponse response = new VehicleResponse();
        BeanUtil.copy(vehicle, response);
        return response;
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public <T> Result<T> updateStatus(UpdateStatusVehicleRequest dto,
                                      HttpServletRequest servletRequest) {
        String loginName = HttpSessionUtil.getLoginName(servletRequest);
        Vehicle vehicle = vehicleMapper.selectByPrimaryKey(dto.getVehicleId());
        vehicle.setStatus(dto.getStatus());
        vehicle.setModifyUser(loginName);
        vehicle.setModifyTime(new Date());
        vehicleMapper.updateStatus(vehicle);
        return new Result<>();
    }


    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public ImportVehicleResponse importVehicle(
            MultipartFile file,
            HttpServletRequest servletRequest,
            HttpServletResponse servletResponse) throws Exception {
        String loginName = HttpSessionUtil.getLoginName(servletRequest);
        List<ImportVehicleRequest> excel = null;
        try {
            InputStream inputStream = file.getInputStream();

            String[] properties = {"vehicleNo", "udf1", "driver", "phone", "udf2"};
            excel = HttpExcel.importExcel(inputStream, ImportVehicleRequest.class, properties);
        } catch (Exception e) {
            // 模板错误，请确认
            Shift.fatal(StatusCode.IMPORT_DATA_ERROR);
        }

        if (excel == null || excel.size() == 0) {
            // 该模板数据为空
            Shift.fatal(StatusCode.IMPORT_DATA_NULL);
        }

        // 失败、成功条数
        int fail = excel.size(), sucess = 0;
        // 失败记录集合
        List<ImportVehicleErrorResponse> errors = new ArrayList<>();

        List<DataItemDetailDTO> vehicleTypes = dataItemDetailApi.getDataItemDetailByCode("Car_Model");

        for (ImportVehicleRequest dto : excel) {
            boolean flag = true;
            Integer carrierId = null;
            Integer vehicleType = null;

            // 1：检验参数
            for (String message : ValidatorUtil.validatorMessages(dto)) {
                ImportVehicleErrorResponse error = new ImportVehicleErrorResponse();
                BeanUtil.copyNonNull(dto, error);

                StringBuilder errorDec = new StringBuilder("【第");
                errorDec.append(dto.getRow()).append("行】").append(message);
                error.setRowMessage(errorDec.toString());

                errors.add(error);
                flag = false;
            }

            if (flag) {
                // 2：检验车牌号
                Vehicle vehicle = vehicleMapper.selectOneByVehicleNoAndDriver(dto.getVehicleNo(), dto.getDriver());
                if (vehicle != null) {
                    // 该车辆数据已存在
                    ImportVehicleErrorResponse error = new ImportVehicleErrorResponse();
                    BeanUtil.copyNonNull(dto, error);

                    StringBuilder errorDec = new StringBuilder("【第");
                    errorDec.append(dto.getRow()).append("行】").append(StatusCode.VEHICLE_DATA_EXIST.message());
                    error.setRowMessage(errorDec.toString());

                    errors.add(error);
                    flag = false;
                }
                
                // 2：检验车牌号合法性
                if (!RegularUtils.carNoJudge(dto.getVehicleNo())) {
                	ImportVehicleErrorResponse error = new ImportVehicleErrorResponse();
                    BeanUtil.copyNonNull(dto, error);

                    StringBuilder errorDec = new StringBuilder("【第");
                    errorDec.append(dto.getRow()).append("行】车牌号错误");
                    error.setRowMessage(errorDec.toString());

                    errors.add(error);
                    flag = false;
                }

                // 3：检验承运人
                if (StringUtils.isNotNull(dto.getUdf2())) {
                    Carrier carrier = carrierMapper.selectOneByCarrierName(dto.getUdf2());
                    if (carrier == null) {
                        // 运输公司/承运人错误
                        ImportVehicleErrorResponse error = new ImportVehicleErrorResponse();
                        BeanUtil.copyNonNull(dto, error);

                        StringBuilder errorDec = new StringBuilder("【第");
                        errorDec.append(dto.getRow()).append("行】运输公司错误");
                        error.setRowMessage(errorDec.toString());

                        errors.add(error);
                        flag = false;
                    } else {
                        carrierId = carrier.getCarrierId();
                    }
                }

                // 4：检验车型
                for (DataItemDetailDTO one : vehicleTypes) {
                    if (dto.getUdf1().equals(one.getItemName())) {
                        vehicleType = one.getDataItemDetailId();
                    }
                }
                if (vehicleType == null) {
                    // 车型错误
                    ImportVehicleErrorResponse error = new ImportVehicleErrorResponse();
                    BeanUtil.copyNonNull(dto, error);

                    StringBuilder errorDec = new StringBuilder("【第");
                    errorDec.append(dto.getRow()).append("行】车型错误");
                    error.setRowMessage(errorDec.toString());

                    errors.add(error);
                    flag = false;
                }
            }

            if (flag) {
                Vehicle vehicle = new Vehicle();
                BeanUtil.copyNonNull(dto, vehicle);
                vehicle.setCreateUser(loginName);
                vehicle.setCreateTime(new Date());
                vehicle.setVehicleType(vehicleType);
                vehicle.setCarrierId(carrierId);
                vehicle.setUdf2(null);
                vehicle.setStatus(BaseIsEnabledEnum.USE.code);
                vehicleMapper.insert(vehicle);
                --fail;
                ++sucess;
            }
        }
        ImportVehicleResponse response = new ImportVehicleResponse();
        response.setFailureCount(fail);
        response.setSucceessCount(sucess);
        response.setItems(errors);
        return response;
    }

    /**
     * 根据查询关键字查询车辆信息，通过车牌号或司机模糊查询
     *
     * @param selectKey
     * @return
     */
    public List<Vehicle> getVehicleInfo(String selectKey) {

        //创建条件构造器
        QueryWrapper<Vehicle> wrapper = new QueryWrapper<>();
        if (selectKey!=null) {
            wrapper.like("VEHICLE_NO", selectKey).or().like("DRIVER", selectKey);
        }

        List<Vehicle> vehicleList = vehicleMapper.selectList(wrapper);
        return vehicleList;
    }
}
